from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, viewsets
from django.db.models import Count, Q
from adserver.models import AdUnit, AdUnitHobby, AdUnitDistrict
from .models import UserFeedback, AdClick
from .serializers import AdUnitHobbySerializer, AdUnitDistrictSerializer


class AdSearchView(APIView):
    """
    广告检索视图
    - 支持根据兴趣标签和地域信息检索广告
    - 优先展示用户反馈好（喜欢次数多）和点击率高的广告
    - 返回广告单元及其关联的创意信息
    """

    def get(self, request):
        # 获取查询参数
        hobby_tag = request.query_params.get('hobby_tag', None)
        province = request.query_params.get('province', None)
        city = request.query_params.get('city', None)
        try:
            limit = int(request.query_params.get('limit'))
        except (TypeError, ValueError):
            limit = None
        # 过滤广告单元
        queryset = AdUnit.objects.all()
        if hobby_tag:
            queryset = queryset.filter(hobbies__hobby_tag=hobby_tag)
        if province:
            queryset = queryset.filter(districts__province=province)
        if city:
            queryset = queryset.filter(districts__city=city)

        # 计算每个广告单元的不同用户喜欢次数和点击次数
        queryset = queryset.annotate(
            like_count=Count('userfeedback__user',
                             filter=Q(userfeedback__feedback='like'),
                             distinct=True),
            dislike_count=Count('userfeedback__user',
                                filter=Q(userfeedback__feedback='dislike'),
                                distinct=True),
            click_count=Count('adclick',
                              distinct=True)
        )

        # 排序逻辑：优先展示喜欢次数多、点击次数多的广告
        queryset = queryset.order_by('-like_count', '-click_count', '-budget_fee')
        if limit and limit > 0:
            queryset = queryset[:limit]  # 使用数据库层分页

        # 返回广告单元数据
        ad_data = []
        for ad_unit in queryset:
            # 获取广告单元关联的创意信息
            creatives = []
            for unit_creative in ad_unit.ad_creatives.all():
                creative = unit_creative.ad_creative
                creatives.append({
                    'creative_id': creative.creative_id,
                    'name': creative.name,
                    'creative_type': creative.get_creative_type_display(),
                    'material_type': creative.get_material_type_display(),
                    'height': creative.height,
                    'width': creative.width,
                    'size': creative.size,
                    'duration': creative.duration,
                    'audit_status': creative.audit_status,
                    'url': creative.url,
                    'create_time': creative.create_time,
                    'update_time': creative.update_time
                })

            ad_data.append({
                'id': ad_unit.unit_id,
                'name': ad_unit.unit_name,
                'budget_fee': ad_unit.budget_fee,
                'like_count': ad_unit.like_count,
                'dislike_count': ad_unit.dislike_count,
                'click_count': ad_unit.click_count,
                'hobbies': [hobby.hobby_tag for hobby in ad_unit.hobbies.all()],
                'districts': [f'{district.province} - {district.city}' for district in ad_unit.districts.all()],
                'creatives': creatives  # 添加创意信息
            })

        return Response(ad_data, status=status.HTTP_200_OK)


class UserFeedbackView(APIView):
    """
    用户反馈视图
    - 记录用户对广告的喜欢或讨厌
    """

    def post(self, request):
        user = request.user  # 获取当前用户
        ad_unit_id = request.data.get('unit_id', None)
        feedback = request.data.get('feedback', None)
        comment = request.data.get('comment', None)  # 获取评论
        # 检查参数是否完整
        if not ad_unit_id or not feedback:
            return Response({'error': 'Missing ad_unit_id or feedback'}, status=status.HTTP_400_BAD_REQUEST)

        # 检查反馈类型是否合法
        if feedback not in ['like', 'dislike']:
            return Response({'error': 'Invalid feedback type'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            ad_unit = AdUnit.objects.get(pk=ad_unit_id)
            # 创建用户反馈记录
            UserFeedback.objects.create(user=user, ad_unit=ad_unit, feedback=feedback, comment=comment)  # 保存评论
            return Response({'status': 'success'}, status=status.HTTP_201_CREATED)
        except AdUnit.DoesNotExist:
            return Response({'error': 'AdUnit not found'}, status=status.HTTP_404_NOT_FOUND)


class AdClickView(APIView):
    """
    广告点击视图
    - 记录用户对广告的点击
    """

    def post(self, request):
        user = request.user  # 获取当前用户
        ad_unit_id = request.data.get('unit_id', None)

        # 检查参数是否完整
        if not ad_unit_id:
            return Response({'error': 'Missing ad_unit_id'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            ad_unit = AdUnit.objects.get(pk=ad_unit_id)
            # 创建广告点击记录
            AdClick.objects.create(user=user, ad_unit=ad_unit)
            return Response({'status': 'success'}, status=status.HTTP_201_CREATED)
        except AdUnit.DoesNotExist:
            return Response({'error': 'AdUnit not found'}, status=status.HTTP_404_NOT_FOUND)


class HobbyViewSet(viewsets.ModelViewSet):
    queryset = AdUnitHobby.objects.all()
    serializer_class = AdUnitHobbySerializer


class DistrictViewSet(viewsets.ModelViewSet):
    queryset = AdUnitDistrict.objects.all()
    serializer_class = AdUnitDistrictSerializer
